今天就直接來設定一下MongoDB以及Spring專案的架構,昨天有提到MongoDB是使用Docker運行的container,
運行指令為
docker run -p 27017:27017 --name native-camp -d mongo
因為是本機端使用就沒設定密碼,這是不好的示範。
然後可以使用Mongo Compass來管理資料庫,我自己使用MongoDB管理工具主要有Compass和Robo 3T,我自己會看要做什麼操作而切換使用的管理工具。
根據Day2分析的架構所設定collections
先把專案會用到的資料夾給新增好,以及新增mode、repository和aspect
application.yml 目前只有連接mongoDB設定
spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/native_camp
然後mode 我自己是習慣使用lombok,真的好用便利,很推薦喔!
這邊先展示Users,但還有些欄位需要新增
package com.mock.nativecamp.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "Users")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
    private String id;
    private String name;
    private String email;
    private String status;
    private String coin;
    private String timezone;
    private String payMethod;
    private String nextPayCheck;
}
然後repository的話也是對應mode事先新增完畢,我這邊做的是log request和response。
這邊展示UsersRepository
package com.mock.nativecamp.repository;
import com.mock.nativecamp.model.Users;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UsersRepository extends MongoRepository<Users, String> {
}
再來是AOP的設定,我覺得AOP在做request和response時很便利
LogAspect
package com.mock.nativecamp.aspect;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Component
@Aspect
@Slf4j
public class LogAspect {
    // this is log API receive request and return response log
    @Pointcut("execution(* com.mock.nativecamp.controller.*.*(..))")
    public void log() {
    }
    @Before("log()")
    public void deBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        RequestLog requestLog = new RequestLog(
                request.getRequestURL().toString(),
                request.getRemoteAddr(),
                classMethod,
                joinPoint.getArgs()
        );
        log.info("request: {}", requestLog.toString());
    }
    @AfterReturning(returning = "result", pointcut = "log()")
    public void doAfterReturning(Object result) {
        log.info("response: {}", result);
    }
    @Data
    private class RequestLog {
        private String url;
        private String ip;
        private String classMethod;
        private Object[] args;
        public RequestLog(String url, String ip, String classMethod, Object[] args) {
            this.url = url;
            this.ip = ip;
            this.classMethod = classMethod;
            this.args = args;
        }
    }
}
下一篇會把各model的設計給完善。